package com.fatsatsuma.spreadsheets;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


/**
 * @author $Id: SpreadsheetWriter.java,v 1.1 2007/06/07 10:12:56 gevans Exp $
 */
public class SpreadsheetWriter {

    private HSSFWorkbook                workbook;

    private Logger                      log     = Logger.getLogger( this.getClass() );

    private List<SpreadsheetCellFormat> formats = null;


    public SpreadsheetWriter() {
        this.workbook = new HSSFWorkbook();
    }


    public void createSheet( String sheetName ) {
        if ( log.isDebugEnabled() ) {
            log.debug( "Creating Sheet " + sheetName );
        }
        workbook.createSheet( sheetName );
    }


    public void createSheets( String ... sheetNames ) {
        for ( String sheetName : sheetNames ) {
            if ( log.isDebugEnabled() ) {
                log.debug( "Creating Sheet " + sheetName );
            }
            workbook.createSheet( sheetName );
        }
    }


    public void setHeaders( String sheetName, String ... headers ) {
        if ( log.isDebugEnabled() ) {
            log.debug( "Writing Headers for Sheet " + sheetName );
        }
        HSSFSheet sheet = workbook.getSheet( sheetName );
        HSSFRow row = sheet.createRow( 0 );
        int count = 0;
        for ( String header : headers ) {
            if ( log.isDebugEnabled() ) {
                log.debug( "HEADER> " + count + ":" + header );
            }
            HSSFCell cell = row.createCell( (short) count++ );
            cell.setCellValue( header );
        }
        row.createCell( (short) count++ );
    }


    public void setDataFormats( List<SpreadsheetCellFormat> formats ) {
        this.formats = formats;
    }


    public void addDataRow( String sheetName, Object ... data ) {
        if ( log.isDebugEnabled() ) {
            log.debug( "Adding Data for Sheet " + sheetName );
        }
        HSSFSheet sheet = workbook.getSheet( sheetName );
        HSSFRow row = sheet.createRow( sheet.getLastRowNum() + 1 );
        int count = 0;
        for ( Object object : data ) {
            HSSFCell cell = row.createCell( (short) count );
            if ( formats == null || formats.size() != data.length ) {
                if ( object != null ) {
                    cell.setCellType( HSSFCell.CELL_TYPE_STRING );
                    cell.setCellValue( String.valueOf( object ) );
                } else {
                    cell.setCellType( HSSFCell.CELL_TYPE_BLANK );
                }
            } else {
                switch ( formats.get( count ) ) {
                    case STRING:
                        cell.setCellType( formats.get( count ).getCellType() );
                        cell.setCellValue( String.valueOf( object ) );
                        break;
                    case NUMERIC:
                        cell.setCellType( formats.get( count ).getCellType() );
                        cell.setCellValue( Double.parseDouble( String.valueOf( object ) ) );
                        break;
                    case BLANK:
                        cell.setCellType( formats.get( count ).getCellType() );
                        break;
                    default:
                        throw new RuntimeException( "Illegal Cell Format" );
                }
            }

            count++;
        }
    }


    public void write( OutputStream outputStream ) throws IOException {
        workbook.write( outputStream );
    }


    public void write( File file ) throws IOException {
        if ( log.isDebugEnabled() ) {
            log.debug( "Writing to file " + file.getAbsolutePath() );
        }
        workbook.write( new FileOutputStream( file ) );
    }
}
